package com.recognition.emergent;

import com.ecortex.emergent.api.EmergentConnection;
import com.ecortex.emergent.api.EmergentDataTable;
import com.ecortex.emergent.api.EmergentException;
import com.recognition.Logger;
import com.recognition.Main;
import com.recognition.image.SnapshotManager;

public class EmergentClient
{
	private static Logger _log = Logger.getLogger();
	
	private EmergentConnection _connection;
	private String ip;	
	private boolean _isConnected = false;	
	private boolean _learnMode = true;
	
	public EmergentClient(String newIp)
	{
		_connection = new EmergentConnection(newIp);
		ip = newIp;
	}
	
	public void run()
	{
		SnapshotManager manager = SnapshotManager.getManager();
		if (_learnMode)
		{
			_connection.RemoveData("snapshots");		
			EmergentDataTable snapshots = new EmergentDataTable("snapshots", new Snapshot(), _connection);
			for (Integer key : manager.getKeys())
			{
				Snapshot snap = new Snapshot();
				Float[] output = new Float[]{(float) 0, (float) 0, (float) 0, (float) 0, (float) 0, (float) 0, (float) 0, (float) 0, (float) 0, (float) 0};
				output[((key & 0xff00) >> 8)] = (float) 1;
				
				snap.Input = manager.getTable(key);
				snap.Output = output;
				snap.Name = manager.getName(key) + "_" + (key & 0xff);
				
				snapshots.add(snap);
			}
			snapshots.Write();		
	        _connection.RunProgram("LeabraTrain");
		}
		else
		{		
			_connection.RemoveData("TrialTestOutputData");	
			_connection.RemoveData("tests");	
			EmergentDataTable testInput = new EmergentDataTable("tests", new TestSnapshot(), _connection);			
			EmergentDataTable testOutput = new EmergentDataTable("TrialTestOutputData", new TrialTestOutputDataRow(), _connection);
			
			TestSnapshot snap = new TestSnapshot();			
			snap.Input = manager.getCurrentTable();
			snap.Name = "network_test";			
			testInput.add(snap);	
			
			if (testInput.size() == 0)				
				return;
		
			testInput.Write();
			_connection.RunProgram("LeabraTrialTest");			
			testOutput.Read();
			
			if (testOutput.size() == 0)
				return;
				
			TrialTestOutputDataRow result = (TrialTestOutputDataRow) testOutput.get(0);
			int winner = -1;
			float act = 0;
			for (int i = 0; i < 2; ++i)
			{
				for (int j = 0; j < 5; ++j)
				{
					if (result.Output[j][i] > act)
					{						
						if (i == 0) winner = j;
						else if (i == 1) winner = 5 + j;
						act = result.Output[j][i];
					}
				}
			}
			
			Main.getWindow().popupTest(winner);
			
		}
	}
	
	public boolean isConnected()
	{
		return _isConnected;
	}
	
	public boolean connect()
	{
		try
		{
			_connection.Initialize();
		}
		catch (EmergentException e) 
		{
			_log.error("EmergentClient: Failed to connect.");
			_log.error("EmergentClient: " + e.getMessage());
            return false;
        }
		
		_log.info("EmergentClient: Connected to " + ip);
		_isConnected = true;
		return true;
	}
	
	public void disconnect()
	{
		if (_connection == null)
			return;
		
		try
		{
			_connection.Shutdown();
		}
		catch (EmergentException e) 
		{
			_log.error("EmergentClient: Failed to disconnect.");
			_log.error("EmergentClient: " + e.getMessage());
			return;
        }
		
		_log.info("EmergentClient: Disconnected");
		_isConnected = false;
	}
	
	public void setMode(boolean learn)
	{
		_learnMode = learn;
	}
}